﻿package  
{

	import fl.controls.ScrollBar;
	import fl.events.ScrollEvent;
	import flash.display.Sprite;
	import flash.display.Stage;
	import com.adobe.serialization.json.JSON;
	import flash.events.Event;
	import flash.text.TextField;

	/**
	 * ...
	 * @author Minfang
	 */
	public class ScrollTable extends Sprite 
	{
		
		
		
		
		
		private var error:int = 0;
		
		private var matrixGroup:Array ;
		
		public var new_stage_height:int;
		
		public var stage_padding_top:int = 1;
		public var stage_padding_bottom:int = 1;
		
		public var stage_padding_left:int = 1;
		public var stage_padding_right:int = 2;
		
		public var line_styles:Object = null;
		
		
		public function ScrollTable(stg:Stage,tableContent:String,globalCss:String) 
		{
			
			
			
			
			var column_extend_value:int = 10;
			
			var row_extend_value:int = 6;
			
			matrixGroup = new Array();
			
			var i1:int, i2:int, i3:int, col:int,row:int,w1:int,w2:int,w3:int,h1:int,h2:int,h3:int;
			
			matrixGroup[0] = new Array();
			matrixGroup[1] =  new Array();
			matrixGroup[2] =  new Array();
			
			matrixGroup[0] [0] = new TablePiece("locked_tl");
			matrixGroup[0] [1] = new TablePiece("locked_top");
			matrixGroup[0] [2] = new TablePiece("locked_tr");
			
			matrixGroup[1] [0] = new TablePiece("locked_left");
			matrixGroup[1] [1] = new TablePiece("body");
			matrixGroup[1] [2] = new TablePiece("locked_right");
			
			matrixGroup[2] [0] = new TablePiece("locked_bl");
			matrixGroup[2] [1] = new TablePiece("locked_bottom");
			matrixGroup[2] [2] = new TablePiece("locked_br");
			
			
			
			//load data 
			var to:Object = JSON.decode(tableContent);
			
			if (to == null) {
				trace("fail to decode json str:", tableContent);
				return;
			}
			
			//trace(tableContent);
			var css1:String ;
			
			if (to['css'] != undefined) {
				globalCss = to['css'];
				//trace(globalCss);
			}
			
			
			if (to['line_styles'] != undefined ) {
				line_styles = to['line_styles'];
			}
			
			for (i1 = 0; i1 < 3; i1++) {
				
				for (i2 = 0; i2 < 3; i2++) {
					if (to[matrixGroup[i1][i2].name] != undefined) {
						//trace ('find ', matrixGroup[i1][i2].name);
						matrixGroup[i1][i2].setContent(to[matrixGroup[i1][i2].name],globalCss);
						
						addChild(matrixGroup[i1][i2].mask);
						
					}
					else {
						//trace ('Not find ', matrixGroup[i1][i2].name);
						matrixGroup[i1][i2] = null;
					}
				}
				
			}
			
			
			//if there is no lock line, the cornor should be null;
			
			if (matrixGroup [0] [1] == null) {
				matrixGroup [0] [0] = null;
				matrixGroup [0] [2] = null;
			}
			
			if (matrixGroup [2] [1] == null) {
				matrixGroup [2] [0] = null;
				matrixGroup [2] [2] = null;
			}
			
			if (matrixGroup [1] [0] == null) {
				matrixGroup [0] [0] = null;
				matrixGroup [2] [0] = null;
			}
			
			if (matrixGroup [1] [2] == null) {
				matrixGroup [0] [2] = null;
				matrixGroup [2] [2] = null;
			}
			
			//if to lock line cross, the cornor must be exist
			if (matrixGroup[1][0] != null && matrixGroup[0][1] != null && matrixGroup[0][0] == null) {
				matrixGroup[0][0] = new TablePiece("empty_tl");
				matrixGroup[0][0].setEmptyCornor(matrixGroup[1][0].num_col, matrixGroup[0][1].num_row);
			}
			
			if (matrixGroup[1][2] != null && matrixGroup[0][1] != null && matrixGroup[0][2] == null) {
				matrixGroup[0][2] = new TablePiece("empty_tr");
				matrixGroup[0][2].setEmptyCornor( matrixGroup[1][2].num_col, matrixGroup[0][1].num_row);
			}
			
			if (matrixGroup[1][2] != null && matrixGroup[2][1] != null && matrixGroup[2][2] == null) {
				matrixGroup[2][2] = new TablePiece("empty_br");
				matrixGroup[2][2].setEmptyCornor( matrixGroup[1][2].num_col, matrixGroup[2][1].num_row);
			}
			
			if (matrixGroup[1][0] != null && matrixGroup[2][1] != null && matrixGroup[2][0] == null) {
				matrixGroup[2][0] = new TablePiece("empty_bl");
				matrixGroup[2][0].setEmptyCornor( matrixGroup[1][0].num_col, matrixGroup[2][1].num_row);
			}
			
			
			
			// end load data
			
			// validate 
			
			
			if (matrixGroup[1][1] == null) {
				trace("body is required");
				error++;
				return;
			}
			
	
			
			
			for (i1 = 0; i1 < 3; i1++) {	
				for (i2 = 0; i2 < 3; i2++) {
					if (matrixGroup[i1][i2] != null) {
						if (matrixGroup[i1][i2].content.isError()) {
							error++;
						}
						
					}
			
				}
			}
			
			var lastFind:int;
				
			for (i1 = 0; i1 < 3; i1++) {
				
				var rr:int = 0;
				for (i2 = 0; i2 < 3; i2++) {
					if (matrixGroup[i1][i2] != null) {
						if (rr == 0) {
							rr = matrixGroup[i1][i2].num_row;
							lastFind = i2;
						}
						else {
							if (rr != matrixGroup[i1][i2].num_row) {
								trace(matrixGroup[i1][i2].name, " number of row ",matrixGroup[i1][i2].num_row," is not equal to ", matrixGroup[i1][lastFind].name,rr);
								error++;
							}
						}
					}
				}
			}
			
			for (i1 = 0; i1 < 3; i1++) {
				
				var cc:int = 0;
				for (i2 = 0; i2 < 3; i2++) {
					if (matrixGroup[i2][i1] != null) {
						if (cc == 0) {
							cc = matrixGroup[i2][i1].num_col;
							lastFind = i2;
						}
						else {
							if (cc != matrixGroup[i2][i1].num_col) {
								trace(matrixGroup[i2][i1].name, " number of column ",matrixGroup[i2][i1].num_col,"is not equal to ",matrixGroup[lastFind][i1].num_col, cc);
								error++;
							}
						}
					}
				}
			}
			
			
			
			
			if (error) {
				trace("There is a error, so give up the next processing");
				return;
			}
			
			///calaculate the talbe size:
			var maxArray:Array ;
			//calculate max_each_column_width, 
			
			var minColumnsLen:Array = new Array;
			
			for (i1 = 0; i1 < 3; i1++) {
				
				maxArray = new Array;
				for (i2 = 0; i2 < 3; i2++) {
					
					if (matrixGroup[i2][i1] != null) {
						maxArray = matrixGroup[i2][i1].content.findMaxColumnLength(maxArray);
					}
				}
				
				for (i2 = 0; i2 < maxArray.length; i2++) {
					minColumnsLen.push(maxArray[i2]);
				}
				
				
				
			}
			
			
			
			//calcualte max_each_row_height 
			var minRowheight:Array = new Array;
			for (i1 = 0; i1 < 3; i1++) {
				
				maxArray = new Array;
				for (i2 = 0; i2 < 3; i2++) {
					
					if (matrixGroup[i1][i2] != null) {
						maxArray = matrixGroup[i1][i2].content.findMaxRowHight(maxArray);
					}
				}
				
				for (i2 = 0; i2 < maxArray.length; i2++) {
					minRowheight.push(maxArray[i2]);
				}
				
				
				
			}
			
			
			// add the extra value to the two array
			
			for (i1 = 0; i1 < minColumnsLen.length; i1++) {
				minColumnsLen[i1] += column_extend_value;
			}
			for (i1 = 0; i1 < minRowheight.length; i1++) {
				minRowheight[i1] += row_extend_value;
			}
			
			
			
			//trace("min columns width:", minColumnsLen);
			//trace("min rows height:", minRowheight);
			
			var totalWidth:int = stg.stageWidth-stage_padding_left-stage_padding_right;
			var totalHeight:int = stg.stageHeight - stage_padding_top-stage_padding_bottom;
			
			var dataWidth:int=totalWidth;
			var dataHeight:int=totalHeight;
			
			
			
			
			
			var actualWidth:int = 0;
			
			for (i2 = 0; i2 < minColumnsLen.length; i2++) {
				actualWidth += minColumnsLen[i2];
			}
			
			var actualHeight:int = 0;
			for (i2 = 0; i2 < minRowheight.length; i2++) {
				actualHeight += minRowheight[i2];
			}
			
			
			var x_scroll_bar_height:int = 20;
			var y_scroll_bar_width:int = 20;
			
			var x_scroll_bar_flag:int = 0;
			var y_scroll_bar_flag:int = 0;
			
			var after_x_scroll_bar_height:int = dataHeight - x_scroll_bar_height;
			var after_y_scroll_bar_width:int = dataWidth - y_scroll_bar_width;
			
			if (dataWidth >= actualWidth && dataHeight >= actualHeight) {
				// no any scroll bar
				totalHeight=dataHeight = actualHeight;
			}
			
			else if ((dataWidth < actualWidth && dataHeight < actualHeight) ||
				(dataWidth < actualWidth && after_x_scroll_bar_height< actualHeight) ||
				(dataHeight < actualHeight && after_y_scroll_bar_width<actualWidth)) {
				//both scroll bar
				
				dataWidth = after_y_scroll_bar_width;
				dataHeight = after_x_scroll_bar_height ;
				x_scroll_bar_flag = 1;
				y_scroll_bar_flag = 1;
			}
			else if (dataWidth < actualWidth) {
				//x scroll bar
				
				dataHeight = actualHeight;
				totalHeight=dataHeight+ x_scroll_bar_height;
				 x_scroll_bar_flag=1
			}
			else {
				// y scroll bar
				dataWidth = after_y_scroll_bar_width;
				y_scroll_bar_flag = 1;
			}
			
			
		
			
			
			
			

			
			if (x_scroll_bar_flag) {
				// add x scroll bar in bottom
				
				var x_scroll_bar_width:int;
				
				
				
				
			}
			
			else {
				//trace("do not need bottom scroll bar",x_scroll_bar_flag);
				
				//do not need scroll bar
				i1 = dataWidth - actualWidth;
				
				i3 = i1 % minColumnsLen.length;
				
					
				i1 -= i3;
				i1 = i1  / minColumnsLen.length;
				
				for (i2 = 0; i2 < minColumnsLen.length; i2++) {
					minColumnsLen[i2] += i1;
					if (i3 > 0) {
						minColumnsLen[i2] ++;
						i3--;
					}
					
					
				}
				
				//trace("real columns width:", minColumnsLen);
			
				
				
			} // end if x_scroll_bar_flag
			
			//depend new column length, reset all columns x;
				
			for (i1=0,col = 0; col < 3; col++) {
				for (i2=0,row = 0; row < 3; row++) {
					if (matrixGroup[row][col] != null) {
						i2 = matrixGroup[row][col].num_col;
						matrixGroup[row][col].content.setColumnsX(minColumnsLen, i1);
					}
				}
				i1 += i2;
			}
			
			w1 = 0;
			if (matrixGroup[1][0] != null) {
				for (i1 = 0; i1 < matrixGroup[1][0].num_col; i1++) {
					w1 += minColumnsLen[i1];
					
				}
				
				for (row = 0; row < 3; row++) {
					if (matrixGroup[row][0] != null) {
						matrixGroup[row][0].mask_width = w1;
						matrixGroup[row][0].mask.x = 0;
						matrixGroup[row][0].content.x = 0;
					}
				}
				
			}
			
			
			
			w3 = 0;
			if (matrixGroup[1][2] != null) {
				for (w3 = 0, i1 = 0; i1 < matrixGroup[1][2].num_col; i1++) {
					w3 += minColumnsLen[minColumnsLen.length-i1-1];
				}
				for (row = 0; row < 3; row++) {
					if (matrixGroup[row][2] != null) {
						matrixGroup[row][2].mask_width = w3;
						matrixGroup[row][2].mask.x = dataWidth - w3;
						matrixGroup[row][2].content.x = dataWidth - w3;
					}
				}
				
			}
			
			for (row = 0; row < 3; row++) {
				if (matrixGroup[row][1] != null) {
					matrixGroup[row][1].mask_width = dataWidth-w1-w3;
					matrixGroup[row][1].mask.x = w1;
					matrixGroup[row][1].content.x = w1;
				}
			}
		
			
			
			
			
			if (y_scroll_bar_flag) {
				// add scroll bar in bottom
			}
			
			else {
				//do not need scroll bar
				
			}
				
				
				//depend new row height, reset all row y;
			
			for (i1=0,row = 0; row < 3; row++) {
				for (i2=0,col = 0; col < 3; col++) {
					if (matrixGroup[row][col] != null) {
						i2 = matrixGroup[row][col].num_row;
						matrixGroup[row][col].content.setRowsY(minRowheight, i1);
						
						//trace(matrixGroup[row][col].name, "Start Index:",i1,"values:", minRowheight);
						//matrixGroup[row][col].content.print_element_coordinate();
					}
				}
				i1 += i2;
			}
			
			h1 = 0;
			if (matrixGroup[0][1] != null) {
				for (h1=0,i1 = 0; i1 < matrixGroup[0][1].num_row; i1++) {
					h1 += minRowheight[i1];
				}
				for (col = 0; col < 3; col++) {
					if (matrixGroup[0][col] != null) {
						matrixGroup[0][col].mask_height = h1;
						matrixGroup[0][col].mask.y = 0;
						matrixGroup[0][col].content.y = 0;
					}
				}
				
			}
			
			h3 = 0;
			if (matrixGroup[2][1] != null) {
				for (h3=0,i1 = 0; i1 < matrixGroup[2][1].num_row; i1++) {
					h3 += minRowheight[minRowheight.length-i1-1];
				}
				for (col = 0; col < 3; col++) {
					if (matrixGroup[2][col] != null) {
						matrixGroup[2][col].mask_height = h3;
						matrixGroup[2][col].mask.y = dataHeight - h3;
						matrixGroup[2][col].content.y = dataHeight - h3;
					}
				}
				
			}
			
			for (col = 0; col < 3; col++) {
				if (matrixGroup[1][col] != null) {
					matrixGroup[1][col].mask_height = dataHeight-h1-h3;
					matrixGroup[1][col].mask.y = h1;
					matrixGroup[1][col].content.y = h1;
				}
			}
		
			
			
			for (row = 0; row < 3; row++) {
				for (col = 0; col < 3; col++) {
					if (matrixGroup[row][col] != null) {
						
						matrixGroup[row][col].content.re_draw(line_styles);
						matrixGroup[row][col].mask.graphics.beginFill(0);
						matrixGroup[row][col].mask.graphics.drawRect( 0,0,
						matrixGroup[row][col].mask_width,matrixGroup[row][col].mask_height );
						matrixGroup[row][col].mask.graphics.endFill();
						
						addChild(matrixGroup[row][col].mask);
						addChild(matrixGroup[row][col].content);
						
						
				
					}	
				}
			}
		
			if (x_scroll_bar_flag) {
				
				 
				
				var xsb:ScrollBar = new ScrollBar();
				xsb.x = matrixGroup[1][1].mask.x;
				xsb.y = totalHeight - x_scroll_bar_height;
				xsb.width = x_scroll_bar_height;
				xsb.height = matrixGroup[1][1].mask_width;
				xsb.enabled = true;
				xsb.setScrollProperties(1000, 0,matrixGroup[1][1].content.real_width-matrixGroup[1][1].mask.width);
				xsb.direction = "horizontal";
				xsb.addEventListener(ScrollEvent.SCROLL, x_scroll);
				this.addChild(xsb);
				//trace("real width:", matrixGroup[1][1].content.real_width);
			}
			
			if (y_scroll_bar_flag) {
				var ysb:ScrollBar = new ScrollBar();
				ysb.x = totalWidth - y_scroll_bar_width;
				ysb.y = matrixGroup[1][1].mask.y;
				ysb.width = y_scroll_bar_width;
				ysb.height = matrixGroup[1][1].mask_height;
				ysb.enabled = true;
				ysb.setScrollProperties(1000, 0, matrixGroup[1][1].content.real_height-matrixGroup[1][1].mask.height);
				ysb.direction = "vertical";
				
				
				
				this.addChild(ysb);
				ysb.addEventListener(ScrollEvent.SCROLL, y_scroll);
				//trace("real height:", matrixGroup[1][1].content.real_height);
				
			}
			
			
			
				
			//end calculate
			
			
			
			//body_data.resetCoordinate();
			
			
			/*
			graphics.lineStyle(1, 0xff0000);
			for (var i1:int = stg.stageHeight; i1 >= 0; i1 -= 50) {
				graphics.moveTo(0, i1);
				graphics.lineTo(stg.stageWidth, i1);
				var tt:TextField = new TextField;
				tt.text = ''+i1;
				
				
				tt.x = stg.width/2;
				tt.y =i1;
				
				addChild(tt);
			}
			
			graphics.lineStyle(1, 0x0000ff);
			for (i1 = stg.stageWidth; i1 >= 0; i1 -= 50) {
				graphics.moveTo(i1, 0);
				graphics.lineTo(i1,stg.stageHeight);
				tt = new TextField;
				tt.text = ''+i1;
				
				
				tt.x = i1;
				tt.y =stg.stageHeight/2+50;
				
				addChild(tt);
			}
			
			*/
			

			new_stage_height = 0;
			if (x_scroll_bar_flag) {
				new_stage_height += x_scroll_bar_height;
			}
			new_stage_height += dataHeight;
			
			
			new_stage_height += stage_padding_top;
			new_stage_height += stage_padding_bottom;

		
		} //end function
		
		public function y_scroll(e:ScrollEvent):void {
			
			//trace(e.currentTarget.scrollPosition);
			for (var col:int = 0;col < 3; col++) {
				if(matrixGroup[1][col] !=null){
					matrixGroup[1][col].content.y = matrixGroup[1][col].mask.y - e.currentTarget.scrollPosition;
				}
			}
			
		}
		
		public function x_scroll(e:ScrollEvent):void {
			
			//trace(e.currentTarget.scrollPosition);
			for (var row:int = 0; row < 3; row++) {
				if (matrixGroup[row][1] != null) {
					matrixGroup[row][1].content.x = matrixGroup[row][1].mask.x  - e.currentTarget.scrollPosition;
				}
			}
			
		}
	
		
	}

}